package com.google.bitcoin.core;

import java.io.IOException;
import java.io.OutputStream;

/**
 * @author apetersson
 */
public class Opcodes {
    // Some constants used for decoding the scripts.
    public static final int OP_PUSHDATA1 = 76;
    public static final int OP_PUSHDATA2 = 77;
    public static final int OP_PUSHDATA4 = 78;
    public static final int OP_DUP = 118;
    public static final int OP_HASH160 = 169;
    public static final int OP_EQUALVERIFY = 136;
    public static final int OP_CHECKSIG = 172;
    public static final int OP_CHECKMULTISIG = 174;
    public static final int CONSTANTS_BASE = 80;
    public static final int OP_0 = 0;


    public static int op_X_fromConstant(int number) { //converts 1-6 to OP_1 - OP_16
        if (number < 1 || number > 16)
            throw new IllegalArgumentException("this number has no corresponding opcode: " + number);
        return number + CONSTANTS_BASE;
    }

    public static int constantFrom_OP_X(int opcode) { //converts OP_1 - OP_16 to a number 1-16
        if (opcode < 81 || opcode > 96) throw new IllegalArgumentException("invalid constant opcode, " + opcode);
        return opcode - CONSTANTS_BASE;
    }

    /**
     * Writes out the given byte buffer to the output stream with the correct opcode prefix
     */
    static void writeBytes(OutputStream os, byte[] buf) throws IOException {
        if (buf.length < OP_PUSHDATA1) {
            os.write(buf.length);
            os.write(buf);
        } else if (buf.length < 256) {
            os.write(OP_PUSHDATA1);
            os.write(buf.length);
            os.write(buf);
        } else if (buf.length < 65536) {
            os.write(OP_PUSHDATA2);
            os.write(0xFF & (buf.length));
            os.write(0xFF & (buf.length >> 8));
            os.write(buf);
        } else {
            throw new RuntimeException("Unimplemented");
        }
    }
}
